# Copyright (c) 2021 Presto Labs Pte. Ltd.
# Author: daniel

import requests
from coin2.exchange.product_info import ProductInfoDefault
from coin2.exchange.symbology import SymbologyInfo


orderbook_unit_map = {}

price_list_cache_map = {}
tick_list_cache_map = {}


def gen_price_tick_size(name: str):
  quote = str.split(name, "-")[1]
  price_list = []
  tick_list = []
  url = "https://api.gopax.co.kr/trading-pairs/{}/price-tick-size".format(name)
  data = requests.get(url).json()
  for info in data:
    price_list.append(float(info['startPrice']))
    tick_list.append(float(info['tickSize']))
  price_list.append(1e09)
  price_list.sort(reverse=True)
  tick_list.sort(reverse=True)

  if len(price_list) > 0 and len(tick_list) > 0:
    price_list_cache_map[quote] = price_list
    tick_list_cache_map[quote] = tick_list
    return True

  return False


def gen_var_ticks(native_symbol: str):
  quote = str.split(native_symbol, "-")[1]
  if quote not in price_list_cache_map:
    if not gen_price_tick_size(native_symbol):
      raise Exception("failed to generate price tick size template")

  price_list = price_list_cache_map[quote]
  tick_list = tick_list_cache_map[quote]
  range_list = list(zip(price_list[:-1], price_list[1:]))
  result = []
  for r, tick in zip(range_list, tick_list):
    assert r[0] >= r[1]
    info = {
        'from': r[1],
        'to': r[0],
        'value': tick,
    }
    result.append([info['from'], info['to'], info['value']])
  return result


def generate():
  mea = 'Spot.Gopax.v1'
  me = 'Spot.Gopax'
  default = ProductInfoDefault()
  symbol_info = SymbologyInfo()
  data = requests.get("https://api.gopax.co.kr/trading-pairs").json()
  orderbook_unit_map.clear()

  pis = []
  for info in data:
    native_base = info['baseAsset']
    native_quote = info['quoteAsset']
    native_symbol = info['name']
    base = symbol_info.native_to_norm_currency(mea, native_base)
    quote = symbol_info.native_to_norm_currency(mea, native_quote)
    symbol = "%s-%s" % (base, quote)

    # orderbook_unit_map[native_symbol.lower()] = info['orderbook_unit_small']

    # price_ticksize = [[
    #     float(each['range_min']),
    #     float(each['next_range_min']),
    #     float(each['price_unit']),
    # ] for each in info['range_price_units']]

    pi = dict(
        symbol=symbol,
        base=base,
        quote=quote,
        native_symbol=native_symbol,
        native_base=native_base,
        native_quote=native_quote,
        is_inverse=False,
        price_ticksize=gen_var_ticks(native_symbol),
        qty_ticksize=0.0001,
        min_amount=float(info['restApiOrderAmountMin']['limitBid']['amount'])
    )

    pi = {**pi, **default.product_info(me, symbol)}
    pis.append(pi)

  pis = sorted(pis, key=lambda x: x['symbol'])
  return pis


def gen_coin1_constants():
  data = generate()
  data = convert_coin1_constants(data)
  return data


def convert_coin1_constants(data):
  native_coin_list = list({info['native_base'].lower() for info in data})
  return {
      "native_coin_list": native_coin_list,
      "orderbook_unit_map": orderbook_unit_map,
  }


if __name__ == "__main__":
  import json
  print(json.dumps(generate(), indent=2))
